/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : app_freertos.c
  * Description        : FreeRTOS applicative file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "app_freertos.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp_ap3216c.h"
#include "bsp_sht20.h"
#include "gpio.h"
#include "algorithm.h"
#include "max30102.h"
#include "MAX30102_use.h"
#include "wifi.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 128 * 4
};
/* Definitions for myTask2 */
osThreadId_t myTask2Handle;
const osThreadAttr_t myTask2_attributes = {
  .name = "myTask2",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 128 * 4
};
/* Definitions for myTask03 */
osThreadId_t myTask03Handle;
const osThreadAttr_t myTask03_attributes = {
  .name = "myTask03",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 1024 * 4
};
/* Definitions for myTask04 */
osThreadId_t myTask04Handle;
const osThreadAttr_t myTask04_attributes = {
  .name = "myTask04",
  .priority = (osPriority_t) osPriorityNormal2,
  .stack_size = 256 * 4
};
/* Definitions for myMutex1 */
osMutexId_t myMutex1Handle;
const osMutexAttr_t myMutex1_attributes = {
  .name = "myMutex1"
};
/* Definitions for myTimerPrint */
osTimerId_t myTimerPrintHandle;
const osTimerAttr_t myTimerPrint_attributes = {
  .name = "myTimerPrint"
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/*--------------------------枚举-----------------------------------------------------*/
enum{
	close=0,
	open=1
}Flag_Status;      //用于记录开关状态

enum{
	Temperature_control_mode=0,
	Moisture_control_mode=1,
	MANUAL_mode=2
}Mode;

int MODE=MANUAL_mode;         //模式
float a=0;


/*-------走廊亮灯模块------------*/
int light_flag=close;             //用于标记光照是否需要开灯的亮度
int Human_infrared_flag=close;       //检测是否有人存在，存在则为open
int slave_light_flag=close;              //使用光照标志与人体红外标志同时控制，slave是否需要开灯

int Human_infrared_numb=0;            //人体红外数据延迟使用
uint16_t light_numb=0;               //记录三合一中光照传感器的光强值

/*-------火焰检测模块------------*/
int fire_flag=close;             //火焰传感器是否检测到火焰
int slave_water_pump_flag=close;  //根据火焰传感器的标志位使用水泵
int fire_beep=close;           //根据是否有火焰存在调用蜂鸣器


/*-------除湿器模块------------*/
int led1_flag=close;      //模拟加热片
int led3_flag=close;      //模拟制冷片
int fan_flag=close;       //风扇开关标志位
int Humidifier_flag=close;     //slave模拟加湿器

SHT20_TemRH_Val val;           //获取温湿度传感器的值
int temp=0,hum=0;              //存储温湿度的数值
int Temperature_threshold=20,Moisture_threshold=50;        //温度阈值湿度阈值


/*-------心率血氧温度体温模块------------*/
int finger=0;               //检测到是否有手指按压MAX30102
float human_temperature=0;           //人体温度
int32_t heart_rate=0,old_heart_rate=0,mistake_heart_rate=0;                   //心率
int32_t blood_oxygen=0,old_blood_oxygen=0,mistake_blood_oxygen=0;                 //血氧
int motor_flag_numb=0;                //用于设置马达与上传数据的情况防止错误数据上传,即当为0并且数据不健康时候才警告处理
int motor_flag=close;

/*-----------------wifi模块------------------------------------------*/
uint8_t USART5_RxBuff[1024]={0}; //接收数据存放位置
volatile uint8_t USART5_RxCounter=0; //标志位
extern int connect_flag;

/* USER CODE END FunctionPrototypes */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */
	ap3216c_init();
	
  /* USER CODE END Init */
  /* creation of myMutex1 */
  myMutex1Handle = osMutexNew(&myMutex1_attributes);

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */
  /* creation of myTimerPrint */
  myTimerPrintHandle = osTimerNew(Print_Callback, osTimerPeriodic, NULL, &myTimerPrint_attributes);

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
	osTimerStart( myTimerPrintHandle,2000);
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */
  /* creation of defaultTask */
  defaultTaskHandle = osThreadNew(myTask_Human_infrared, NULL, &defaultTask_attributes);

  /* creation of myTask2 */
  myTask2Handle = osThreadNew(SHT11_Task, NULL, &myTask2_attributes);

  /* creation of myTask03 */
  myTask03Handle = osThreadNew(max30102_Task, NULL, &myTask03_attributes);

  /* creation of myTask04 */
  myTask04Handle = osThreadNew(Handle_flag_Task, NULL, &myTask04_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}
/* USER CODE BEGIN Header_myTask_Human_infrared */
/**
* @brief Function implementing the defaultTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_myTask_Human_infrared */
void myTask_Human_infrared(void *argument)
{
  /* USER CODE BEGIN defaultTask */
  /* Infinite loop */
	
  for(;;)
  {
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_4)==1)
		{
			Human_infrared_flag=open;
			/*-------------------人体红外延时，使得检测到人存在的时间更久，使得检测更加平滑----------*/
			if(Human_infrared_numb<=120000){    
				Human_infrared_numb+=10;
			}		
		}
		else
		{
			if(Human_infrared_numb>=0){
				Human_infrared_numb-=2;
			}
			if(Human_infrared_numb<=0){
				Human_infrared_flag=close;
			}
			
		}
		osMutexAcquire(myMutex1Handle,osWaitForever); // 添加互斥锁进行接收iic数据(检测光照强度)
		light_numb=ap3216c_read_ambient_light();
		osMutexRelease(myMutex1Handle);
		if(light_numb<=10){
			light_flag=open; //光照强度太低
		}else{
			light_flag=close;
		}
		
		/*---------------根据人体红外与光照标志位设置外部模拟led的标志位-------------------------*/
		if(light_flag==1&&Human_infrared_flag==1){
				slave_light_flag=open;
		}else{
				slave_light_flag=close;
		}
		osDelay(300);
  }
  /* USER CODE END defaultTask */
}

/* USER CODE BEGIN Header_SHT11_Task */
/**
* @brief Function implementing the myTask2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_SHT11_Task */
void SHT11_Task(void *argument)
{
  /* USER CODE BEGIN myTask2 */
  /* Infinite loop */
  for(;;)
  {
		osMutexAcquire(myMutex1Handle,osWaitForever); // 添加互斥锁进行接收iic数据(检测温湿度)
		val=BSP_SHT20_GetData();
		osMutexRelease(myMutex1Handle);
		temp=val.Tem;
		hum=val.Hum;
		if(MODE==Temperature_control_mode){
			//比较温度阈值与当前温度的差别修改标志位
			if(temp>Temperature_threshold+6){
				led3_flag=open;
				fan_flag=open;
				led1_flag=close;
				Humidifier_flag=close;
			}
			else if(temp<Temperature_threshold-6){
				led1_flag=open;
				fan_flag=open;
				led3_flag=close;
				Humidifier_flag=close;
			}
			else if(temp>Temperature_threshold-6&&temp<Temperature_threshold+6){
				led1_flag=close;
				led3_flag=close;
				fan_flag=close;
				Humidifier_flag=close;
			}
			
		}
		if(MODE==Moisture_control_mode){
			//比较湿度阈值与当前温度的差别修改标志位
			if(hum>Moisture_threshold+10){
				led1_flag=open;
				led3_flag=open;
				fan_flag=open;
				Humidifier_flag=close;
			}
			else if(hum<Moisture_threshold-10){
				led1_flag=close;
				led3_flag=close;
				fan_flag=close;
				Humidifier_flag=open;
			}
			else if(hum>Moisture_threshold-10&&hum<Moisture_threshold+10){
				led1_flag=close;
				led3_flag=close;
				fan_flag=close;
				Humidifier_flag=close;	
			}
			
		}
		
		/*--------读取火焰传感器数据----------------------*/
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_3)!=0){
			fire_flag=open;
			fire_beep=open;
			slave_water_pump_flag=open;
		}else{
			fire_flag=close;
			fire_beep=close;
			slave_water_pump_flag=close;
		}
    osDelay(300);
  }
  /* USER CODE END myTask2 */
}

/* USER CODE BEGIN Header_max30102_Task */
/**
* @brief Function implementing the myTask03 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_max30102_Task */
void max30102_Task(void *argument)
{
  /* USER CODE BEGIN myTask03 */
  /* Infinite loop */
  for(;;)
  { 
		osMutexAcquire(myMutex1Handle,osWaitForever); 
		maxim_max30102_init();
		osMutexRelease(myMutex1Handle);

		osMutexAcquire(myMutex1Handle,osWaitForever); 
		finger=finger_press_check() ;
		osMutexRelease(myMutex1Handle);
		if(finger==1){
			osMutexAcquire(myMutex1Handle,osWaitForever); // 添加互斥锁进行接收iic数据
			Update_HeartRateInfo(&human_temperature,&mistake_heart_rate,&mistake_blood_oxygen);
			osMutexRelease(myMutex1Handle);// 添加互斥锁进行接收iic数据	
			if(mistake_heart_rate>30&&mistake_heart_rate<110){
				 heart_rate=mistake_heart_rate;
			}
			if(mistake_blood_oxygen>20&&mistake_blood_oxygen<101){
				 blood_oxygen=mistake_blood_oxygen;
			}
			if(heart_rate>50&&blood_oxygen>90&&heart_rate<110&&blood_oxygen<101){   
					motor_flag_numb+=5;
					old_blood_oxygen=blood_oxygen;
					old_heart_rate=heart_rate;
					motor_flag=close;
			}
			else if(heart_rate>0&&blood_oxygen>0&&heart_rate<50&&blood_oxygen<90)
				{
				motor_flag_numb--;   //降到0或0以下则才可以判断病人不健康
				
				if(motor_flag_numb<=0){
					if(heart_rate!=0&&blood_oxygen!=0)
						motor_flag=open;
				}else{
					blood_oxygen=old_blood_oxygen; //用于防止数据不稳定防止数据产生错误
					heart_rate=old_heart_rate;
				}
			}
		}
		else{
			heart_rate=0;
			blood_oxygen=0;
			motor_flag=close;
			motor_flag_numb=0;
		}
    osDelay(300);
  }
  /* USER CODE END myTask03 */
}

/* USER CODE BEGIN Header_Handle_flag_Task */
/**
* @brief Function implementing the myTask04 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Handle_flag_Task */
void Handle_flag_Task(void *argument)
{
  /* USER CODE BEGIN myTask04 */
  /* Infinite loop */
  for(;;)
  {
		//if(connect_flag==open)   //判断wifi连接成功
		/*----------------走廊亮灯设备控制模块------------------------------------*/
				if(slave_light_flag==open){
					 //打开slave 模拟的灯
				}
				else{
						//关闭slave模拟的灯
				}
		/*----------------红眼检测设备控制模块------------------------------------*/
				if(fire_beep==open&&slave_water_pump_flag==open){
					 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,open);
					//打开HAAS端的水泵
				}
				else{
					 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,close);
					//关闭haas端的水泵
				}
	/*----------------心率血氧检测设备控制模块------------------------------------*/
				if(motor_flag==open){
					 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,open);
				}
				else{
					 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,close);
				}
	/*----------------温湿度检测设备控制模块------------------------------------*/			
				if(led1_flag==open){
					 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,open);
				}
				else{
					 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,close);
				}
				if(led3_flag==open){
					 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,open);
				}
				else{
					 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,close);
				}
				if(fan_flag==open){
					 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_6,open);
				}
				else{
					 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_6,close);
				}
				if(Humidifier_flag==open){
					 //slave模拟的加湿器打开
				}
				else{
					 //slave模拟的加湿器关闭
				}
		
    osDelay(100);
  }
  /* USER CODE END myTask04 */
}

/* Print_Callback function */
void Print_Callback(void *argument)
{
  /* USER CODE BEGIN Print_Callback */
	if(connect_flag==1) {
			 // 第一部分：设备状态
    // 一次性发送完整数据，避免分段延迟
ESP8266_USART("MODE=%d,light=%d,fire=%d,fire_pump=%d,fire_beep=%d,led1=%d,led3=%d,fan=%d,humidifier=%d,temp=%d,hum=%d,temp_th=%d,hum_th=%d,finger=%d,heart_rate=%d,blood_oxygen=%d,motor=%d\r\n",
             MODE, slave_light_flag, fire_flag, slave_water_pump_flag, fire_beep,
             led1_flag, led3_flag, fan_flag, Humidifier_flag,
             temp, hum, Temperature_threshold, Moisture_threshold,
             finger, heart_rate, blood_oxygen, motor_flag);
// 只需要一个延迟，确保发送完成
osDelay(30);
	}
  /* USER CODE END Print_Callback */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart == &huart5)
	{
		USART5_RxCounter=1;//此变量置1，则代表wifi发过来了数据
		/* */
		if(connect_flag==1)
		{
			u1_USART("wifi send:%s!\r\n",USART5_RxBuff);
			
			if(MODE==MANUAL_mode)
			{
				if(strstr(USART5_RxBuff,"open_led1")){
					led1_flag=open;     //开启加热片
				}
				if(strstr(USART5_RxBuff,"open_led3")){
					led3_flag=open;
				}
				if(strstr(USART5_RxBuff,"open_fan")){
					fan_flag=open;               //开启制冷片
				}
				if(strstr(USART5_RxBuff,"open_Humidifier")){
					Humidifier_flag=open;
				}
				
				if(strstr(USART5_RxBuff,"close_led1")){
					 led1_flag=close;
				}
				if(strstr(USART5_RxBuff,"close_led3")){
					 led3_flag=close;
				}
				if(strstr(USART5_RxBuff,"close_fan")){
					 fan_flag=close;
				}
				if(strstr(USART5_RxBuff,"close_Humidifier")){
					Humidifier_flag=close;
				}
			}
			
			if(MODE==Temperature_control_mode)  //调节阈值
			{
					if(strstr(USART5_RxBuff,"add_threshold"))
					{
						if(Temperature_threshold<40)
							Temperature_threshold+=2;
					}
					if(strstr(USART5_RxBuff,"reduce_threshold"))
					{
						if(Temperature_threshold>10)
							Temperature_threshold-=2;	
					}
			}
			
			if(MODE==Moisture_control_mode)
			{
					 if(strstr(USART5_RxBuff,"add_threshold"))
					{
						if(Moisture_threshold<70)
							Moisture_threshold+=2;
					}
					if(strstr(USART5_RxBuff,"reduce_threshold"))
					{
						if(Moisture_threshold>30)
							Moisture_threshold-=2;	
					}
			}
			
			if(strstr(USART5_RxBuff,"open_MANUAL")){
				MODE=MANUAL_mode;
				led1_flag=close;
				led3_flag=close;
				fan_flag=close;
				Humidifier_flag=close;
			}
			if(strstr(USART5_RxBuff,"open_Temperature")){
				MODE=Temperature_control_mode;	
				led1_flag=close;
				led3_flag=close;
				fan_flag=close;
				Humidifier_flag=close;
			}
			if(strstr(USART5_RxBuff,"open_Moisture")){
				MODE=Moisture_control_mode;
				led1_flag=close;
				led3_flag=close;
				fan_flag=close;
				Humidifier_flag=close;
			}
			ESP8266_USART("send ok\r\n");
			memset(USART5_RxBuff,0,1024);	
		}
		
		
		HAL_UARTEx_ReceiveToIdle_IT(&huart5,USART5_RxBuff,1024);
	}
	
}

/* USER CODE END Application */

